package com.smartStatus.websocket.message;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @ClassName : OneToOneSending
 * @Author : lby
 * @Date: 2021/6/17 15:32
 * @Description : 一对一发送
 */
@Data
@Slf4j
@Component
@ServerEndpoint("/client/{userId}")
public class OneToOneSending {


    /**
     * 定义一个socket连接池
     */
    private static final ConcurrentHashMap<String, OneToOneSending> SOCKET_POOL = new ConcurrentHashMap<>();

    /**
     * 定义当前在线总人数
     */
    private static final AtomicInteger ONLINE_USERS = new AtomicInteger(0);


    private Session session;
    private String userId;

    /**
     * 建立socket连接
     * 建立连接时需要userId
     */
    @OnOpen
    public void openWebsocket(Session session, @PathParam("userId") String userId) {
        this.session=session;
        this.userId=userId;
        // 判断当前用户是否已经连接
        if (SOCKET_POOL.containsKey(userId)) {
            log.error("当前用户已连接");
        } else {
            // 连接改用户，在线用户加一
            SOCKET_POOL.put(userId, this);
            ONLINE_USERS.incrementAndGet();
            log.info("当前用户连接socket成功:{}", userId);
            log.info("当前系统总在线人数:{}",ONLINE_USERS.get());
            this.sendSuccessMessage("连接成功");
        }
    }


    /**
     * 关闭socket连接
     * @param session
     */
    @OnClose
    public void closeWebsocket(Session session){
        // 如果当前用户的确处于在线状态，下线
        if (SOCKET_POOL.containsKey(userId)){
            SOCKET_POOL.remove(userId);
            log.info("用户断开连接:{}",userId);
            // 在线人数减一
            ONLINE_USERS.decrementAndGet();
            log.info("当前系统总在线人数:{}",ONLINE_USERS.get());
        }
    }


    /**
     * 当用户收到信息时
     * @param message
     * @param session
     */
    @OnMessage
    public void getMessage(String message,Session session){
        // 用户传输的消息不能为空
        if (StringUtils.isNotBlank(message)){
            JSONObject newMessage = JSON.parseObject(message);
            // 消息的发送者
            newMessage.put("fromUserId",userId);
            // 消息的接受者
            String toUserId = newMessage.get("toUserId").toString();
            // 消息的接受者必须在线，才可以接受消息
            if (SOCKET_POOL.containsKey(toUserId)){
                // 发送消息
                SOCKET_POOL.get(toUserId).sendSuccessMessage(message);
            }
            else {
                log.error("对方不在线，请重试");
            }
        }
        else {
            log.error("发送的消息为空，请重试");
        }
    }



    /**
     * 连接出错
     * @param throwable
     */
    @OnError
    public void errorSocket(Throwable throwable){
        throwable.printStackTrace();
        log.error("系统内部错误:{}",throwable.getMessage());
    }



    /**
     * 当用户连接socket成功时，返回成功数据
     *
     * @param message
     */
    private void sendSuccessMessage(String message) {
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
